package com.k8s.base.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * 配置结构定义
 */
@Entity
@Table(name = "sys_setting_struct", uniqueConstraints = {
    @UniqueConstraint(columnNames = {"name"})
})
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class SettingStruct implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 顺序号
     */
    @NotNull
    @Column(name = "seq", nullable = false)
    private Integer seq;

    /**
     * 引用名
     */
    @NotNull
    @Column(name = "name", nullable = false)
    private String name;

    /**
     * 文本名
     */
    @NotNull
    @Column(name = "label", nullable = false)
    private String label;

    /**
     * 提示信息
     */
    @Column(name = "tip")
    private String tip;

    /**
     * 是否是可公开设置
     */
    @NotNull
    @Column(name = "is_public", nullable = false)
    private Boolean isPublic;

    /**
     * 启用此配置的等级（二进制按位“或”运算）
     */
    @NotNull
    @Column(name = "enable_level", nullable = false)
    private Integer enableLevel;

    /**
     * 编辑页：在编辑页中是否允许编辑（与enable_level同样的做法）
     */
    @NotNull
    @Column(name = "editable_flag")
    private Integer editableFlag;

    /**
     * 编辑页：在编辑页中是否可见（与enable_level同样的做法）
     */
    @Column(name = "visibility_flag")
    private Integer visibilityFlag;

    /**
     * 继承等级
     */
    @Column(name = "inheritable_flag")
    private Integer inheritableFlag;

    /**
     * 允许前端应用读取配置项的范围，可以指定多个值，使用“,”分隔（如：CUSTOMER_APP,EMPLOYEE_APP,H5,WEB等）
     */
    @Column(name = "frontend_accessible_scope")
    private String frontendAccessibleScope;

    /**
     * 值类型：NONE、STRING、INTEGER、NUMBER、DATE、DATETIME、TEXT、IMAGE
     */
    @NotNull
    @Column(name = "value_type", nullable = false)
    private String valueType;

    /**
     * 值选项（JSON:{"value":"","text":""}）
     */
    @Column(name = "value_options")
    private String valueOptions;

    /**
     * 默认值
     */
    @Column(name = "default_value")
    private String defaultValue;

    /**
     * 父配置项
     */
    @ManyToOne
    @NotFound(action = NotFoundAction.IGNORE)
    private SettingStruct parent;

    /**
     * 服务名
     */
    @Column(name = "service_name")
    private String serviceName;

    /**
     * 配置子项
     */
    @OneToMany(mappedBy = "parent", cascade = {CascadeType.REMOVE})
    @JsonIgnore
    @NotFound(action = NotFoundAction.IGNORE)
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Set<SettingStruct> children = new HashSet<>();

    public SettingStruct() {}

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getSeq() {
        return seq;
    }

    public SettingStruct seq(Integer seq) {
        this.seq = seq;
        return this;
    }

    public void setSeq(Integer seq) {
        this.seq = seq;
    }

    public String getName() {
        return name;
    }

    public SettingStruct name(String name) {
        this.name = name;
        return this;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLabel() {
        return label;
    }

    public SettingStruct label(String label) {
        this.label = label;
        return this;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getTip() {
        return tip;
    }

    public SettingStruct tip(String tip) {
        this.tip = tip;
        return this;
    }

    public void setTip(String tip) {
        this.tip = tip;
    }

    public Boolean getIsPublic() {
        return isPublic;
    }

    public SettingStruct isPublic(Boolean isPublic) {
        this.isPublic = isPublic;
        return this;
    }

    public void setIsPublic(Boolean isPublic) {
        this.isPublic = isPublic;
    }

    public Integer getEnableLevel() {
        return enableLevel == null ? 0 : enableLevel;
    }

    public SettingStruct enableLevel(Integer enableLevel) {
        this.enableLevel = enableLevel;
        return this;
    }

    public void setEnableLevel(Integer enableLevel) {
        this.enableLevel = enableLevel;
    }

    public String getValueType() {
        return valueType;
    }
    public SettingStruct valueType(String valueType) {
        this.valueType = valueType;
        return this;
    }
    public void setValueType(String valueType) {
        this.valueType = valueType;
    }

    public String getValueOptions() {
        return valueOptions;
    }
    public SettingStruct valueOptions(String valueOptions) {
        this.valueOptions = valueOptions;
        return this;
    }
    public void setValueOptions(String valueOptions) {
        this.valueOptions = valueOptions;
    }

    public void setDefaultValue(String defaultValue) {
        this.defaultValue = defaultValue;
    }
    public String getDefaultValue() {
        return defaultValue;
    }
    public SettingStruct defaultValue(String defaultValue) {
        this.defaultValue = defaultValue;
        return this;
    }

    public SettingStruct getParent() {
        return parent;
    }

    public SettingStruct parent(SettingStruct settingStruct) {
        this.parent = settingStruct;
        return this;
    }

    public void setParent(SettingStruct settingStruct) {
        this.parent = settingStruct;
    }

    public Set<SettingStruct> getChildren() {
        return children;
    }

    public SettingStruct children(Set<SettingStruct> settingStructs) {
        this.children = settingStructs;
        return this;
    }

    public SettingStruct addChildren(SettingStruct settingStruct) {
        children.add(settingStruct);
        settingStruct.setParent(this);
        return this;
    }

    public SettingStruct removeChildren(SettingStruct settingStruct) {
        children.remove(settingStruct);
        settingStruct.setParent(null);
        return this;
    }

    public void setChildren(Set<SettingStruct> settingStructs) {
        this.children = settingStructs;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        SettingStruct settingStruct = (SettingStruct) o;
        if (settingStruct.id == null || id == null) {
            return false;
        }
        return Objects.equals(id, settingStruct.id);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(id);
    }

    public Integer getEditableFlag() {
        return editableFlag;
    }

    public void setEditableFlag(Integer editableFlag) {
        this.editableFlag = editableFlag;
    }

    public SettingStruct editableFlag(Integer editableFlag) {
        this.editableFlag = editableFlag;
        return this;
    }

    public Integer getVisibilityFlag() {
        return visibilityFlag;
    }

    public void setVisibilityFlag(Integer visibilityFlag) {
        this.visibilityFlag = visibilityFlag;
    }

    public SettingStruct visibilityFlag(Integer visibilityFlag) {
        this.visibilityFlag = visibilityFlag;
        return this;
    }

    public Integer getInheritableFlag() {
        return inheritableFlag == null ? 0 : inheritableFlag;
    }

    public void setInheritableFlag(Integer inheritableFlag) {
        this.inheritableFlag = inheritableFlag;
    }

    public SettingStruct inheritableFlag(Integer inheritableFlag) {
        this.inheritableFlag = inheritableFlag;
        return this;
    }

    public String getFrontendAccessibleScope() {
        return frontendAccessibleScope;
    }

    public void setFrontendAccessibleScope(String frontendAccessibleScope) {
        this.frontendAccessibleScope = frontendAccessibleScope;
    }

    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    @Override
    public String toString() {
        return "SettingStruct{" +
            "id=" + id +
            ", seq=" + seq +
            ", name='" + name + '\'' +
            ", label='" + label + '\'' +
            ", tip='" + tip + '\'' +
            ", isPublic=" + isPublic +
            ", enableLevel=" + enableLevel +
            ", editableFlag=" + editableFlag +
            ", visibilityFlag=" + visibilityFlag +
            ", inheritableFlag=" + inheritableFlag +
            ", frontendAccessibleScope='" + frontendAccessibleScope + '\'' +
            ", valueType='" + valueType + '\'' +
            ", valueOptions='" + valueOptions + '\'' +
            ", defaultValue='" + defaultValue + '\'' +
            '}';
    }

}
